package cn.tedu.icop.order.service.impl;
import cn.tedu.icop.api.domain.GunStatusUpdateParam;
import cn.tedu.icop.api.model.RestResult;
import cn.tedu.icop.api.service.StationRemoteService;
import cn.tedu.icop.api.service.UserRemoteService;
import cn.tedu.icop.order.constant.MqttConstant;
import cn.tedu.icop.order.mqtt.MqttProducer;
import cn.tedu.icop.order.pojo.dto.ChargingDto;
import cn.tedu.icop.order.pojo.param.OrderAddParam;
import cn.tedu.icop.order.pojo.po.OrderMQPO;
import cn.tedu.icop.order.rabbit.RabbitMQOrderProducer;
import cn.tedu.icop.order.service.OrderService;
import cn.tedu.icop.order.xxljob.XxlJobInfo;
import cn.tedu.icop.order.xxljob.XxlJobService;
import com.alibaba.fastjson2.JSON;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.biz.client.ExecutorBizClient;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.biz.model.TriggerParam;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import com.xxl.job.core.glue.GlueTypeEnum;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.util.XxlJobRemotingUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private UserRemoteService userRemoteService;
    @Autowired
    private StationRemoteService stationRemoteService;

    @Autowired
    private RabbitMQOrderProducer rabbitMQOrderProducer;

    @Autowired
    private XxlJobSpringExecutor xxlJobExecutor;

    @Autowired
    private XxlJobService xxlJobService;

    @Override
    public String createOrder(OrderAddParam orderAddParam) {
        //1.获取用户车辆信息
        RestResult<Integer> userBindVehicleId = userRemoteService.getUserBindVehicleId(orderAddParam.getUserId());
        log.debug("调用用户服务，获取用户车辆id为{}",userBindVehicleId);
        //2.调用设备服务更新枪状态
        GunStatusUpdateParam gunStatusUpdateParam = new GunStatusUpdateParam();
        gunStatusUpdateParam.setId(orderAddParam.getGunId());
        gunStatusUpdateParam.setGunStatus(2);//1.表示空闲，2表示使用中
        RestResult restResult = stationRemoteService.editGunStatus(gunStatusUpdateParam);
        log.debug("调用设备服务，更新枪状态，更新结果 {}",restResult);
        //3.启动充电业务
        //3.1获取订单id
        String orderNo=getOrderNo(orderAddParam);
        //3.2启动充电
        //startCharging(orderNo,orderAddParam.getPileId(),orderAddParam.getGunId());
        //4.发送延迟消息(检查设备自检情况)
        //sendRabbitMQMessage(orderNo);
        //5.发送延迟消息 (检查异常订单：例如快充一个小时应该结束，但是订单状态并没有结束，一直显示充电中，此订单可以标记为异常订单。)
        //6.用定时任务调度进行订单超时检查(解决第五点发送延迟消息问题)
        //如何启动xxl-job去执行任务调度？

        //xxlJobService.run(3,orderNo);//执行一次（run）
        //xxlJobService.triggerJob(3);//login,start

        addAndTrigerJob(orderNo);
        return "100001";
    }

    private void addAndTrigerJob(String orderNo) {
        MultiValueMap<String, String> map=new LinkedMultiValueMap<>();
        map.add("jobGroup","2");
        map.add("jobDesc","hello new job");
        //map.add("addTime",null);
        //map.add("updateTime",null);
        map.add("author", "tony");
        map.add("alarmEmail", "");
        map.add("scheduleType", "CRON");
        map.add("scheduleConf",XxlJobService.generateCronExpressionFor2MinutesLater());
        map.add("misfireStrategy", "DO_NOTHING"); // 错过调度策略
        map.add("executorRouteStrategy","FIRST");
        map.add("executorHandler", "checkTimeOutOrder");
        map.add("executorParam", orderNo);
        map.add("executorBlockStrategy", "SERIAL_EXECUTION");
        map.add("executorTimeout", "0");
        map.add("executorFailRetryCount", "0");
        map.add("glueType", "BEAN");
        map.add("glueSource", ""); // Glue 源码
        map.add("glueRemark", "GLUE代码初始化"); // Glue 源码
        //map.add("glueUpdatetime",null); // Glue 更新时间
        map.add("childJobId", ""); // 子任务ID
        map.add("triggerStatus","0");
        map.add("triggerLastTime", "0");
        map.add("triggerNextTime", "0");

        String jobId = xxlJobService.addJob(map);
        xxlJobService.triggerJob(Integer.valueOf(jobId));
    }

    @XxlJob("checkTimeOutOrder")
    public ReturnT<String> checkTimeOutOrder() {
        String jobParam = XxlJobHelper.getJobParam();
        System.out.println("java, Hello new xxl-job #####,"+System.currentTimeMillis()+","+jobParam);
        //.....执行订单任务检查.....
        return ReturnT.SUCCESS;
    }
    @XxlJob("doCheckTimeoutOrder")
    public ReturnT<String> doCheckTimeoutOrder() {
        String jobParam = XxlJobHelper.getJobParam();
        System.out.println("java, Hello xxl-job ~~~,"+System.currentTimeMillis()+","+jobParam);
        return ReturnT.SUCCESS;
    }

    private void sendRabbitMQMessage(String orderNo) {
        OrderMQPO orderMQPO = new OrderMQPO();
        orderMQPO.setOrderNo(orderNo);
        rabbitMQOrderProducer.sendOrder(orderMQPO);
    }


    @Autowired
    private MqttProducer mqttProducer;

    private void startCharging(String orderNo,Integer pileId,Integer gunId) {
        String topic= MqttConstant.TOPIC_START_CHARGING_PREFIX +"/"+ pileId;///topic/start/1
        //pileId,gunId,msg;
        ChargingDto chargingDto = new ChargingDto();
        chargingDto.setOrderNo(orderNo);
        chargingDto.setPileId(pileId);
        chargingDto.setGunId(gunId);
        chargingDto.setMsg("start charging");
        String message = JSON.toJSONString(chargingDto);
        Boolean result = mqttProducer.send(topic, message);
        log.debug("发送消息结果{}",result);
    }
    private String getOrderNo(OrderAddParam orderAddParam) {
        StringBuilder sb=new StringBuilder();
        sb.append(orderAddParam.getPileId()).append("_")
                .append(orderAddParam.getGunId()).append("_").append(System.currentTimeMillis());
        return sb.toString();
    }
}
